"""
MDC 日志格式化器

扩展标准日志格式化器，自动包含 MDC 上下文信息
"""

import json
import logging
from typing import Optional

from app.utils.mdc_context import mdc


class MDCFormatter(logging.Formatter):
    """MDC 感知的日志格式化器"""

    def __init__(
        self,
        fmt: Optional[str] = None,
        datefmt: Optional[str] = None,
        include_mdc: bool = True,
        mdc_format: str = "json",  # "json" 或 "keyvalue"
    ):
        """
        初始化 MDC 格式化器

        Args:
            fmt: 日志格式字符串
            datefmt: 日期格式字符串
            include_mdc: 是否包含 MDC 上下文
            mdc_format: MDC 上下文格式 ("json" 或 "keyvalue")
        """
        if fmt is None:
            fmt = "%(asctime)s [%(levelname)s] %(name)s:%(lineno)d - %(message)s"

        super().__init__(fmt, datefmt)
        self.include_mdc = include_mdc
        self.mdc_format = mdc_format

    def format(self, record: logging.LogRecord) -> str:
        """格式化日志记录，包含 MDC 上下文"""
        # 获取 MDC 上下文
        mdc_context = mdc.get_context()

        if self.include_mdc and mdc_context:
            # 将 MDC 上下文添加到日志记录中
            if self.mdc_format == "json":
                mdc_str = json.dumps(mdc_context, ensure_ascii=False, default=str)
                record.mdc = f" | MDC: {mdc_str}"
            else:
                # key=value 格式
                mdc_pairs = [f"{k}={v}" for k, v in mdc_context.items()]
                record.mdc = f" | {' '.join(mdc_pairs)}"
        else:
            record.mdc = ""

        return super().format(record)


class StructuredMDCFormatter(logging.Formatter):
    """结构化 MDC 日志格式化器（适合 JSON 日志）"""

    def __init__(self, fmt: Optional[str] = None, datefmt: Optional[str] = None):
        if fmt is None:
            fmt = "%(asctime)s"

        super().__init__(fmt, datefmt)

    def format(self, record: logging.LogRecord) -> str:
        """格式化日志记录为结构化 JSON"""
        # 基础日志信息
        log_data = {
            "timestamp": self.formatTime(record),
            "level": record.levelname,
            "logger": record.name,
            "message": record.getMessage(),
            "module": record.module,
            "function": record.funcName,
            "line": record.lineno,
        }

        # 添加异常信息
        if record.exc_info:
            log_data["exception"] = self.formatException(record.exc_info)

        # 添加 MDC 上下文
        mdc_context = mdc.get_context()
        if mdc_context:
            log_data["mdc"] = mdc_context

        # 添加额外的记录属性
        for key, value in record.__dict__.items():
            if key not in log_data and not key.startswith("_"):
                log_data[key] = value

        return json.dumps(log_data, ensure_ascii=False, default=str)


def create_mdc_logger(name: str, level: int = logging.INFO) -> logging.Logger:
    """
    创建配置了 MDC 格式化器的日志记录器

    Args:
        name: 日志记录器名称
        level: 日志级别

    Returns:
        logging.Logger: 配置好的日志记录器
    """
    logger = logging.getLogger(name)
    logger.setLevel(level)

    # 避免重复添加处理器
    if not logger.handlers:
        handler = logging.StreamHandler()
        formatter = MDCFormatter(
            fmt="%(asctime)s [%(levelname)s] %(name)s:%(lineno)d - %(message)s%(mdc)s", datefmt="%Y-%m-%d %H:%M:%S"
        )
        handler.setFormatter(formatter)
        logger.addHandler(handler)

    return logger
